package cn.jnetty.ioc.executer;

import cn.jnetty.ioc.executer.pool.JnettyRunnablePool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
 * @author 猪哥亮
 * @email 1030681978@qq.com
 * @date 2020/4/6 18:30
 * 描述：
 */
public abstract class AbstractJnettyRunable implements Runnable {
    private final Logger logger = LoggerFactory.getLogger(AbstractJnettyRunable.class);
    /**
     * 线程池
     */
    private final Executor executor;


    /**
     * 选择器wakenUp状态标记
     */
    protected final AtomicBoolean wakenUp = new AtomicBoolean();

    /**
     * 任务队列
     */
    private final Queue<Runnable> taskQueue = new ConcurrentLinkedQueue<>();
    /**
     * 线程锁
     */
    private final Object lock = new Object();
    /**
     * 线程名称
     */
    private String threadName;

    /**
     * 线程管理对象
     */
    protected JnettyRunnablePool selectorRunnablePool;


    AbstractJnettyRunable(Executor executor, String threadName, JnettyRunnablePool selectorRunnablePool) {
        this.executor = executor;
        this.threadName = threadName;
        this.selectorRunnablePool = selectorRunnablePool;
        openSelector();
    }

    /**
     * 获取selector并启动线程
     */
    private void openSelector() {
        executor.execute(this);
    }

    @Override
    public void run() {
        Thread.currentThread().setName(this.threadName);
        processTaskQueue();
    }

    /**
     * 注册一个任务并激活selector
     *
     * @param task
     */
    protected final void registerTask(Runnable task) {
        taskQueue.add(task);
        synchronized (lock) {
            try {
                if (!wakenUp.get()) {
                    wakenUp.set(true);
                    openSelector();
                }
            } catch (Exception throwable) {
                logger.error("任务执行失败", throwable);
            }
        }
    }

    /**
     * 执行队列里的任务
     */
    private void processTaskQueue() {
        for (; ; ) {
            synchronized (lock) {
                try {
                    final Runnable task = taskQueue.poll();
                    if (task == null) {
                        wakenUp.set(false);
                        break;
                    }
                    task.run();
                } catch (Exception e) {
                    logger.error("线程池任务执行异常" + threadName, e);
                }
            }
        }
    }

    /**
     * 获取线程管理对象
     *
     * @return
     */
    public JnettyRunnablePool getSelectorRunnablePool() {
        return selectorRunnablePool;
    }

    /**
     * 性能监控使用
     * 获取当前堆积的任务数量
     *
     * @return
     */
    public long getTaskCount() {
        return taskQueue.size();
    }

    public String getThreadName() {
        return threadName;
    }
}